package com.tanhua.server.service;

import cn.hutool.core.collection.CollUtil;
import com.tan.model.domain.ErrorResult;
import com.tan.model.domain.UserInfo;
import com.tan.model.enums.CommentType;
import com.tan.model.mongo.Movement;
import com.tan.model.mongo.Visitors;
import com.tan.model.vo.MovementsVo;
import com.tan.model.vo.PageResult;
import com.tan.model.vo.VisitorsVo;
import com.tanhua.autoconfig.template.OssTemplate;
import com.tanhua.commons.utils.Constants;
import com.tanhua.dubbo.api.CommentApi;
import com.tanhua.dubbo.api.MoventApi;
import com.tanhua.dubbo.api.UserInfoapi;
import com.tanhua.dubbo.api.VisitorsApi;
import com.tanhua.server.exception.BusinessException;
import com.tanhua.server.interceptor.Userthread;
import org.apache.dubbo.config.annotation.DubboReference;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;

import java.io.IOException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.stream.Collectors;

@Service
public class Moventservice {
    @DubboReference
    private MoventApi moventApi;
    @DubboReference
    private CommentApi commentApi;
    @Autowired
    private OssTemplate ossTemplate;
    @DubboReference
    UserInfoapi userInfoApi;
    @DubboReference
    VisitorsApi visitorsApi;
    @Autowired
    MqMessageService mqMessageService;
    @Autowired
    RedisTemplate<String, String> redisTemplate;
    public void publishMovement(Movement movement, MultipartFile[] imageContent) throws IOException {
      //1.判断发布动态的内容是否存在
        if(movement==null||movement.getTextContent()==null){
            throw new BusinessException(ErrorResult.contentError());
        }
        //2.获取当前用户id
        Long userId = Userthread.getUser().getId();
        //3.将内容上传到阿里云oss，获取请求地址
        List<String> urls = new ArrayList<>();
        for (MultipartFile multipartFile : imageContent) {
          String url =  ossTemplate.uploadFile(multipartFile.getOriginalFilename(),multipartFile.getInputStream());
          urls.add(url);
        }
        //4.将数据封装到Movement对象中
        movement.setUserId(userId);
        movement.setMedias(urls);
        //5.调用api发布动态
        moventApi.postMovement(movement);
    }
    //查询个人动态
    public PageResult allMovements(Integer page, Integer pagesize, Long userId) {

        //1.根据用户id查询动态  （PageResult-----movent）
      PageResult pageResult=  moventApi.findUserid(page,pagesize,userId);
       //2.获取PageResult中的items集合
        List<Movement> items = (List<Movement>) pageResult.getItems();
      // 3.判断items集合是否为空
        if(items==null){
            return pageResult;
        }

        //获得用户信息
       UserInfo userInfo = userInfoApi.getUserInfo(userId);
        List<MovementsVo> list = new ArrayList<>();
        //4.循环数据列表
        for (Movement item : items) {
            //5.一个Movent对象转换为vo对象
           MovementsVo vo = MovementsVo.init(userInfo, item);
            String key = Constants.MOVEMENT_LIKE_HASHKEY+item.getId();
            String HashKey = Constants.MOVEMENT_LIKE_HASHKEY+Userthread.getUser().getId();
            if(redisTemplate.opsForHash().hasKey(key,HashKey)){
                vo.setHasLiked(1);
            }
           list.add(vo);

        }

        //6.构建返回值
       PageResult pr = new PageResult(page,pagesize,list.size(),list);
         return pr;
    }

    public PageResult FindfriendMovements(Integer page, Integer pagesize) {
        //1.查询好友的用户id
       Long userid= Userthread.getUser().getId();
        //2.调用api查询好友动态类表
        List<Movement> items = moventApi.findFriendMovements(page, pagesize, userid);
        return getPageResult(page, pagesize, items);
    }

    private PageResult getPageResult(Integer page, Integer pagesize, List<Movement> items) {
        //3.判断列表是否为空
        if(items ==null){
            return new PageResult();
        }
        //4.提取动态发布人的id列表
        List<Long> ids = CollUtil.getFieldValues(items, "userId", Long.class);
        List<MovementsVo> movementsVos = new ArrayList<>();
        //5.根据id列表查询用户详情
        for (Long id : ids) {
            //6.循环动态列表，构建vo对象
            UserInfo userInfo = userInfoApi.getUserInfo(id);
           for (Movement item : items) {
               if(item.getUserId().equals(id)){
                   MovementsVo vo = MovementsVo.init(userInfo, item);
                   String key = Constants.MOVEMENT_LIKE_HASHKEY+item.getId();
                   String HashKey = Constants.MOVEMENT_LIKE_HASHKEY+Userthread.getUser().getId();
                   if(redisTemplate.opsForHash().hasKey(key,HashKey)){
                       vo.setHasLiked(1);
                   }
                   movementsVos.add(vo);
               }
           }
        }
        PageResult pr = new PageResult(page, pagesize,movementsVos.size(),movementsVos);

        //7.构建返回值
        return pr;
    }

    public PageResult queryRecommendMovements(Integer page, Integer pagesize) {
        Long userId = Userthread.getUser().getId();
        //从redis中获取推荐数据
        String key = Constants.MOVEMENTS_RECOMMEND+ userId;
        String pid = redisTemplate.opsForValue().get(key);
        //判断推荐数据是否存在
        List<Movement> list = new ArrayList<>();
        if(redisTemplate.hasKey(key)){
            //如果存在，处理pid数据 get MOVEMENTS_RECOMMEND_1
            //"2562,3639,2063,3448,2128,2597,2893,2333,3330,2642,2541,3002,3561,3649,2384,2504,3397,2843,2341,2249"
            String[] split = pid.split(",");
            if((page-1)*pagesize<split.length){
          List<Long> ids = Arrays.stream(split).skip((page-1)*pagesize).limit(pagesize).map(Long::parseLong).collect(Collectors.toList());
                //调用api查询推荐动态数据列表
          list = moventApi.findFriendMovementsbyids(ids);
            }


        }else{
            //如果不存在，则调用api随机构建10条动态数据
        list=  moventApi.setRedisRecommendMovements(pagesize);
        }



        //调用公共方法构造返回值
        return getPageResult(page, pagesize, list);
    }

    public MovementsVo getMovement(String id) {
        mqMessageService.sendLogService(Userthread.getUser().getId(),"0202","movement",id);
        Movement movement = moventApi.getMovement(id);

        if(movement!=null){
            Long userId = movement.getUserId();
            UserInfo userInfo = userInfoApi.getUserInfo(userId);
            return MovementsVo.init(userInfo,movement);
        }
      return null;

    }

    public Integer getLikeCount(String Moventventid) {
        //1.调用api查询是否已经点赞了
      Boolean aBoolean =  commentApi.getbooleanlike(Moventventid, Userthread.getUser().getId());
        //2.如果已经点赞了抛出异常
        if(aBoolean){
            throw new BusinessException(ErrorResult.likeError());
        }
        //3.如果没有点赞，调用api将数据保存到Mongodb中
       Integer integer = commentApi.publishComment(Moventventid,null,Userthread.getUser().getId(), CommentType.LIKE.getType());
        //4.拼接redis中的key值存入redis中

        String key = Constants.MOVEMENT_LIKE_HASHKEY+Moventventid;
        String HashKey = Constants.MOVEMENT_LIKE_HASHKEY+Userthread.getUser().getId();
        redisTemplate.opsForHash().put(key,HashKey,"1");
        return integer;


    }

    public Integer getdisLikeCount(String moventid) {
        //1.调用api查询是否已经点赞了
        Boolean aBoolean =  commentApi.getbooleanlike(moventid, Userthread.getUser().getId());
        //2.如果没有点赞了抛出异常
        if(!aBoolean){
            throw new BusinessException(ErrorResult.disLikeError());
        }
        //3.如果已经点赞，调用api删除Mongodb中的数据
        Integer integer = commentApi.deletelike(moventid,Userthread.getUser().getId(), CommentType.LIKE.getType());
        //4.拼接redis中的key值从redis中删除
        String key = Constants.MOVEMENT_LIKE_HASHKEY+moventid;
        String HashKey = Constants.MOVEMENT_LIKE_HASHKEY+Userthread.getUser().getId();
        redisTemplate.opsForHash().delete(key,HashKey);
     return integer;
    }

    public Integer getLoveCount(String Moventventid) {
        //1.调用api查询是否已经点赞了
        Boolean aBoolean =  commentApi.getbooleanlove(Moventventid, Userthread.getUser().getId());
        //2.如果已经点赞了抛出异常
        if(aBoolean){
            throw new BusinessException(ErrorResult.loveError());
        }
        //3.如果没有点赞，调用api将数据保存到Mongodb中
        Integer integer = commentApi.publishComment(Moventventid,null,Userthread.getUser().getId(), CommentType.LOVE.getType());
        //4.拼接redis中的key值存入redis中

        String key = Constants.MOVEMENT_LOVE_HASHKEY+Moventventid;
        String HashKey = Constants.MOVEMENT_LOVE_HASHKEY+Userthread.getUser().getId();
        redisTemplate.opsForHash().put(key,HashKey,"1");
        return integer;


    }

    public Integer getdisLoveCount(String moventid) {
        //1.调用api查询是否已经点赞了
        Boolean aBoolean =  commentApi.getbooleanlove(moventid, Userthread.getUser().getId());
        //2.如果没有点赞了抛出异常
        if(!aBoolean){
            throw new BusinessException(ErrorResult.disloveError());
        }
        //3.如果已经点赞，调用api删除Mongodb中的数据
        Integer integer = commentApi.deletelike(moventid,Userthread.getUser().getId(), CommentType.LOVE.getType());
        //4.拼接redis中的key值从redis中删除
        String key = Constants.MOVEMENT_LOVE_HASHKEY+moventid;
        String HashKey = Constants.MOVEMENT_LOVE_HASHKEY+Userthread.getUser().getId();
        redisTemplate.opsForHash().delete(key,HashKey);
        return integer;
    }

    public List<VisitorsVo> queryVisitorsList() {
        //redis对应的键（类似于mysql的表名）
        String key = Constants.VISITOR_USER;
        //redis中hash值的hashkey
        String hashKey = Userthread.getUser().getId().toString();
        //获取redis对应键的值（只是hash值所以还要hashkey）
      String s = (String)   redisTemplate.opsForHash().get(key,hashKey);
      if(s==null){
          s="0";
      }
      Long time = Long.valueOf(s);
     Long currentuserid =Userthread.getUser().getId();
        //调用api查询数据List<Visitors>
        List<VisitorsVo> list = new ArrayList<>();
        List<Visitors> visitors = visitorsApi.queryVisitorsList(currentuserid,time);
        if(visitors!=null){
            for (Visitors visitor : visitors) {
                Long visitorUserId = visitor.getVisitorUserId();
                UserInfo userInfo = userInfoApi.getUserInfo(visitorUserId);
                VisitorsVo visitorsVo = VisitorsVo.init(userInfo, visitor);
                list.add(visitorsVo);

            }
        }
        return list;
    }
}
